import type { App } from 'vue';

import type { SFCWithInstall } from '#/components';
import { isNumber, isString } from '@/utils/is';

export const noop = () => {};

export function addUnit(value: string | number, defaultUnit = 'px') {
  if (!value) return '';
  if (isString(value)) {
    return value;
  } else if (isNumber(value)) {
    return `${value}${defaultUnit}`;
  }
}

export function S4() {
  return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);
}

export function guid() {
  return S4() + S4() + '-' + S4() + '-' + S4() + '-' + S4() + '-' + S4() + S4() + S4();
}

/**
 *
 * @param main 父组件
 * @param extra 子组件 { child1, child2 }
 * @returns main
 */
export const withInstall = <T, E extends Record<string, any>>(main: T, extra?: E) => {
  (main as SFCWithInstall<T>).install = (app: App): void => {
    for (const comp of [main, ...Object.values(extra ?? {})]) {
      app.component(comp.name, comp);
    }
  };

  if (extra) {
    for (const [key, comp] of Object.entries(extra)) {
      (main as any)[key] = comp;
    }
  }
  return main as SFCWithInstall<T> & E;
};

export function stringParseJson(data) {
  const dataTemp = data.replace(/\n/g, '\\n').replace(/\r/g, '\\r');
  return JSON.parse(dataTemp);
}
